/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.wdb.listener;

import org.glassfish.tyrus.server.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vacoor.nothing.common.util.Throwables;
import org.vacoor.nothing.wdb.websocket.DatabaseEndpoint;
import org.vacoor.nothing.wdb.websocket.SshProxyEndpoint;
import org.vacoor.nothing.wdb.websocket.TerminalEndpoint;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.websocket.DeploymentException;
import java.util.HashSet;
import java.util.Set;

/**
 * @author vacoor
 */
public class WebSocketServerListener implements ServletContextListener {
    private static final Logger LOG = LoggerFactory.getLogger(WebSocketServerListener.class);
    private static final String WEB_SOCKET_PORT_PARAM = "webSocketPort";
    private static final String WEB_SOCKET_PATH_PARAM = "webSocketPath";

    private static final Integer DEFAULT_WEB_SOCKET_PORT = 8025;
    private static final String DEFAULT_WEB_SOCKET_PATH = "/ws";

    protected ServletContext servletContext;
    protected Server webSocketServer;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        this.servletContext = sce.getServletContext();

        String contextPath = servletContext.getContextPath();
        contextPath = contextPath != null ? contextPath : "";

        String wsPath = servletContext.getInitParameter(WEB_SOCKET_PATH_PARAM);
        wsPath = wsPath != null ? wsPath : DEFAULT_WEB_SOCKET_PATH;
        wsPath = wsPath.startsWith("/") ? wsPath.substring(1) : wsPath;

        String wsPortStr = servletContext.getInitParameter(WEB_SOCKET_PORT_PARAM);
        int wsPort = wsPortStr != null ? Integer.valueOf(wsPortStr) : DEFAULT_WEB_SOCKET_PORT;

        LOG.info("start websocket server, port: {}, path: {}", wsPort, wsPath);
        Set<Class<?>> endpoints = new HashSet<Class<?>>();
        endpoints.add(TerminalEndpoint.class);
        endpoints.add(SshProxyEndpoint.class);
        endpoints.add(DatabaseEndpoint.class);
        try {
            webSocketServer = new Server(null, wsPort, contextPath + "/" + wsPath, endpoints);
            webSocketServer.start();
        } catch (DeploymentException e) {
            Throwables.unchecked(e);
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        LOG.info("stop websocket server...");
        if (webSocketServer != null) {
            webSocketServer.stop();
        }
    }
}
